package com.luoxiang.socialandroid.base;

import static com.luoxiang.lib_common.common.Constants.MmkvConst.ACCID;
import static com.luoxiang.lib_common.common.Constants.MmkvConst.KEY;
import static com.luoxiang.lib_common.common.Constants.MmkvConst.KEY_CHECKSUM;
import static com.luoxiang.lib_common.common.Constants.MmkvConst.KEY_CURRTIME;
import static com.luoxiang.lib_common.common.Constants.MmkvConst.KEY_NONCE;
import static com.luoxiang.lib_common.common.Constants.MmkvConst.TOKEN;

import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Lifecycle;

import com.blankj.utilcode.util.LogUtils;
import com.google.gson.Gson;
import com.jaeger.library.StatusBarUtil;
import com.jeremyliao.liveeventbus.LiveEventBus;
import com.luck.picture.lib.utils.DensityUtil;
import com.luoxiang.socialandroid.app.MyAppliaction;
import com.luoxiang.lib_common.bean.CallEvaluateInfoResult;
import com.luoxiang.socialandroid.bean.NumberBean;
import com.luoxiang.lib_common.dialog.EvaluateDialog;
import com.luoxiang.socialandroid.dialog.GiftSuspensionDialog;
import com.luoxiang.socialandroid.dialog.LoadingDialog;
import com.luoxiang.socialandroid.dialog.MassageSuspensionDialog;
import com.luoxiang.socialandroid.utils.AESUtil;
import com.luoxiang.socialandroid.utils.MmkvUtil;
import com.luoxiang.socialandroid.utils.NetUtils;
import com.lxj.xpopup.XPopup;
import com.lxj.xpopup.enums.PopupAnimation;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.uinfo.UserService;
import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;
import com.netease.yunxin.kit.chatkit.ui.custom.GiftAttachment;
import com.netease.yunxin.kit.conversationkit.ui.model.ConversationBean;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

/**
 * @Description TODO
 * @systemUser Administrator
 * @Author LiangXin
 * @Date 08-18-2022 周四 13:44
 */
public abstract class BaseActivity extends AppCompatActivity {
    private MyAppliaction appliaction;
    private DataStorageUtils dataStorageUtils;
    private String tag = this.getClass().getName();
    private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    private LoadingDialog dialog;
    public static String path, key;
    public boolean isShowGift = true;
    public long time = System.currentTimeMillis();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //禁止页面被截屏、录屏
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
        appliaction = MyAppliaction.getMyAppliaction();
        addActivity();
        //全局没有标题栏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        initLayout(savedInstanceState);
        initView();
        initListener();
        dataStorageUtils = new DataStorageUtils(this);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        LiveEventBus.<IMMessage>get("receivedGift").observe(this, imMessage -> {
            if (!isShowGift || !MyAppliaction.getMyAppliaction().whetherReceivePopovers) {
                return;
            }
            if (getLifecycle().getCurrentState() == Lifecycle.State.RESUMED) {
                if (System.currentTimeMillis() < (time + 2000)) {
                    return;
                }
                time = System.currentTimeMillis();
                Integer accId = MmkvUtil.INSTANCE.decodeInt(ACCID);
                if (accId == null || imMessage.getFromAccount().equals(accId.toString())) {
                    return;
                }
                if (imMessage.getFromAccount().equals("10000001")) {
                    return;
                }
                if (imMessage.getAttachment() != null && imMessage.getAttachment() instanceof GiftAttachment) {
                    GiftSuspensionDialog giftSuspensionDialog = new GiftSuspensionDialog(this);
                    giftSuspensionDialog.setData(imMessage);
                    new XPopup.Builder(this)
                            .popupAnimation(PopupAnimation.ScaleAlphaFromCenter)
                            .hasShadowBg(false)
                            .isViewMode(true)
                            .isRequestFocus(false)
                            .isClickThrough(true)
                            .offsetY(DensityUtil.dip2px(this, 176))
                            .asCustom(giftSuspensionDialog)
                            .show();
                }
                Resources resources = this.getResources();
                DisplayMetrics dm = resources.getDisplayMetrics();
                int screenHeight = dm.heightPixels / 5;
                MassageSuspensionDialog massageSuspensionDialog = new MassageSuspensionDialog(this);
                massageSuspensionDialog.setData(imMessage);
                new XPopup.Builder(this)
                        .popupAnimation(PopupAnimation.ScaleAlphaFromCenter)
                        .hasShadowBg(false)
                        .isViewMode(true)
                        .isRequestFocus(false)
                        .isClickThrough(true)
                        .offsetY(dm.heightPixels - screenHeight)
                        .asCustom(massageSuspensionDialog)
                        .show();
            }
        });
        LiveEventBus.<String>get("showEvaluateDialog").observe(this, s -> {
            if (getLifecycle().getCurrentState() == Lifecycle.State.RESUMED) {
                getCallEvaluateInfo(s);
            }
        });
    }

    /**
     * 压缩图片质量
     */
    public static Bitmap compressBitmap(Bitmap bitmap) {

        int maxSize = 300 * 1024;//最大文件大小300kb
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        int quality = 90;
        while (byteArrayOutputStream.toByteArray().length > maxSize) { // 循环判断如果压缩后图片是否大于maxSize字节,大于继续压缩
            byteArrayOutputStream.reset(); // 重置baos即清空baos
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream);// 这里压缩quality%，把压缩后的数据存放到byteArrayOutputStream中
            quality -= 5;
        }
        LogUtils.e(byteArrayOutputStream.toByteArray().length / 1024 + "kb");
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());

        Bitmap decodeBitmap = BitmapFactory.decodeStream(byteArrayInputStream, null, null);// 把ByteArrayInputStream数据生成bitmap
        try {
            byteArrayInputStream.close();
            byteArrayOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return decodeBitmap;

    }

    public String getkey(String picturePaths) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd/HHmmss/");
        Date date = new Date(System.currentTimeMillis());
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        //文件后缀   例如：.png
        String fileType = picturePaths.substring(picturePaths.lastIndexOf("."));
        key = simpleDateFormat.format(date) + uuid + fileType;
        LogUtils.i("pathiii", key);
        return key;
    }


    private void getCallEvaluateInfo(String channelId) {
        NetUtils.getInstance().getApiService().getEvaluationInfo(MmkvUtil.INSTANCE.decodeString(TOKEN), channelId)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<NumberBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(NumberBean numberBean) {
                        String data = numberBean.getData();
                        String decryptStr;
                        try {
                            decryptStr = AESUtil.aesDecryptString(data, KEY);
                            LogUtils.i("decryptStrdelete", decryptStr);
                            Gson gson = new Gson();
                            CallEvaluateInfoResult callEvaluateInfoResult = gson.fromJson(decryptStr, CallEvaluateInfoResult.class);
                            if (callEvaluateInfoResult.getData() != null) {
                                EvaluateDialog evaluateDialog = new EvaluateDialog(BaseActivity.this);
                                evaluateDialog.setData(channelId, callEvaluateInfoResult.getData());
                                new XPopup.Builder(BaseActivity.this)
                                        .asCustom(evaluateDialog)
                                        .show();
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    /**
     * 所有监听的方法都在该类中实现
     */
    protected abstract void initListener();

    /**
     * 初始化布局
     *
     * @param savedInstanceState
     */
    protected abstract void initLayout(Bundle savedInstanceState);

    /**
     * 初始化View 主要是使用findviewbyid的 如果你用的是ButterKnife 这个方法可以忽略
     */
    protected abstract void initView();

    /**
     * 添加activity 控制activity的关闭
     */
    public void addActivity() {
        appliaction.addActivity(this);
    }

    /**
     * 移除当前的页面管理器的页面
     */
    public void removeActivity() {
        appliaction.removeActivity(this);
    }

    /**
     * 销毁当前的activity
     */
    public void destroyActivity() {
        appliaction.destroyActivity(this);
    }

    /**
     * 界面销毁 (1)关闭所有activity
     */
    public void finishAll() {
        appliaction.finishAll();
    }

    /**
     * 界面销毁 (2)退出整个程序
     */
    public void exit() {
        appliaction.exit();
    }

    /**
     * 不设置flags,不需要返回值的页面跳转
     * <p>
     * <p>
     * 当前Activity
     *
     * @param c   要跳转的class
     * @param map 传输数据的键值对 没有时为null
     * @param b   是否关闭当前页面 为true时关闭,false时保留
     */
    public void activityPageChange(Class<?> c, Map<String, Object> map,
                                   boolean b) {
        // 这里的页面关闭可控制
        appliaction.activityPageChange(this, c, map, -1, false, 0, b);
    }

    //    将StatusBar设置为透明
    public void setStatusBarTranslucent() {
        StatusBarUtil.setTranslucentForImageViewInFragment(this,
                0, null);
        StatusBarUtil.setLightMode(this);
    }


    /**
     * 设置flags,不需要返回值的页面跳转
     * <p>
     * <p>
     * 当前Activity
     *
     * @param c     要跳转的class
     * @param map   传输数据的键值对 没有时为null
     * @param flags 为要跳转的页面设置的flags 没有时为-1
     * @param b     是否关闭当前页面 为true时关闭,false时保留
     */
    public void activityPageChange(Class<?> c, Map<String, Object> map,
                                   int flags, boolean b) {
        // 这里的页面关闭可控制
        appliaction.activityPageChange(this, c, map, flags, false, 0, b);
    }

    /**
     * 设置flags,需要返回值的页面跳转
     * <p>
     * <p>
     * 当前Activity
     *
     * @param c           要跳转的class
     * @param map         传输数据的键值对 没有时为null
     * @param flags       为要跳转的页面设置的flags 没有时为-1
     * @param requestCode 跳转页面调用startActivityForResult() 对应的请求码
     * @param b           是否关闭当前页面 为true时关闭,false时保留
     */
    public void activityPageChange(Class<?> c, Map<String, Object> map,
                                   int flags, int requestCode, boolean b) {
        // 这里的页面关闭可控制
        appliaction.activityPageChange(this, c, map, flags, true,
                requestCode, b);
    }

    /**
     * 获取页面传输过程传输的非基本类型数据
     *
     * @param key
     * @return
     */
    public Object getMapData(String key) {
        return appliaction.getMapData(key);
    }

    /**
     * 判断内存卡是否存在
     *
     * @return
     */
    public static boolean isSDCardExist() {
        return DataStorageUtils.isSDCardExist();
    }

    /**
     * 获取sd卡剩余的空间大小 单位是byte
     *
     * @return
     */
    public static long getSDFreeSize() {
        return DataStorageUtils.getSDFreeSize();
    }

    /**
     * 根据键字符串，存储一个字符串值
     *
     * @param key
     * @param value
     * @return 返回提交是否成功
     */
    public boolean putString(String key, String value) {
        return dataStorageUtils.putString(key, value);
    }

    /**
     * 根据key值得到存储结果，如果没有找到value就返回null
     *
     * @param key
     * @return
     */
    public String getString(String key) {
        return dataStorageUtils.getString(key);
    }

    /**
     * 根据键字符串，存储一个整型值, 值不能为-1
     *
     * @param key
     * @param value 不能为-1
     * @return 返回提交是否成功
     */
    public boolean putInt(String key, int value) {
        return dataStorageUtils.putInt(key, value);
    }

    /**
     * 根据key值得到存储结果，如果没有找到value就返回-1
     *
     * @param key
     * @return
     */
    public int getInt(String key) {
        return dataStorageUtils.getInt(key);
    }

    /**
     * 根据key值移除对应的数据
     *
     * @param key
     * @return
     */
    public boolean remove(String key) {
        return dataStorageUtils.remove(key);
    }

    /**
     * 吐司
     *
     * @param message
     */
    public void toast(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }

    public void log(String s) {
        Log.i(tag, s);
    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        appliaction = null;
        dataStorageUtils = null;
    }

    /**
     * 请求头传参方式
     */
    public void getRequest() {
        String apiKey = "17SgH6kkUNk8tyxjR6rbXEDiIR4P3nQh";//prod环境
        String nonce = (int) (Math.random() * 9000 + 1000) + "";//四位随机数
        String currTime = System.currentTimeMillis() + "";//当前时间戳
        String value = apiKey + nonce + currTime;
        MessageDigest messageDigest = null;
        try {
            messageDigest = MessageDigest.getInstance("sha1");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        messageDigest.update(value.getBytes());
        byte[] bytes = messageDigest.digest();

        //转换成16进制
        int len = bytes.length;
        StringBuilder buf = new StringBuilder(len * 2);
        for (int j = 0; j < len; j++) {
            buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
            buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
        }
        String newCheckSum = buf.toString();
        MmkvUtil.INSTANCE.encode(KEY_NONCE, nonce);
        MmkvUtil.INSTANCE.encode(KEY_CURRTIME, currTime);
        MmkvUtil.INSTANCE.encode(KEY_CHECKSUM, newCheckSum);
    }

    //    public void getdecrypt(String data){
//        String decryptStr = null;
//        try {
//            decryptStr = AESUtil.aesDecryptString(data, KEY);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
    public void showLoading() {
        if (dialog == null) {
            dialog = new LoadingDialog(this);
        }
        dialog.show();
    }


    public void clearLoading() {
        if (dialog != null) {
            dialog.dismiss();
        }
    }


    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

}
